package com.bj58.disconf.web.controllers;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baidu.disconf.core.common.constants.DisConfigTypeEnum;
import com.bj58.disconf.web.PrintBeat;
import com.bj58.disconf.web.common.annotation.NoAuth;
import com.bj58.disconf.web.common.exception.DocumentNotFoundException;
import com.bj58.disconf.web.controllers.BaseController;
import com.bj58.disconf.web.controllers.JsonActionResult;
import com.bj58.disconf.web.controllers.config.dto.ConfigFullModel;
import com.bj58.disconf.web.controllers.config.validator.ConfigValidator4Fetch;
import com.bj58.disconf.web.service.config.bo.Config;
import com.bj58.disconf.web.service.config.form.ConfForm;
import com.bj58.disconf.web.service.config.service.ConfigFetchMgr;
import com.bj58.disconf.web.service.config.utils.ConfigUtils;
import com.bj58.disconf.web.utils.GuiceDI;
import com.bj58.wf.mvc.ActionResult;
import com.bj58.wf.mvc.annotation.Path;

/**
 * 配置获取Controller, Disconf-client专门使用的
 *
 * @author lemon
 * @version 2014-6-16
 */
@Path("/api/config")
public class ConfigFetcherController extends BaseController {

    protected static final Logger LOG = LoggerFactory.getLogger(ConfigFetcherController.class);

    private final ConfigValidator4Fetch configValidator4Fetch = GuiceDI.getInstance(ConfigValidator4Fetch.class);

    private final ConfigFetchMgr configFetchMgr = GuiceDI.getInstance(ConfigFetchMgr.class);

    /**
     * 获取指定app env version 的配置项列表
     *
     * @param confForm
     *
     * @return
     */
    @Path("/list")
    public ActionResult getList(ConfForm confForm) {
        try {
            PrintBeat.printBeat(beat);
            return new JsonActionResult(getListImp(confForm, true));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @NoAuth
    @Path("/simple/list")
    public ActionResult getSimpleList(ConfForm confForm) {
        PrintBeat.printBeat(beat);
        try {
            return new JsonActionResult(getListImp(confForm, false));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取配置项 Item
     *
     * @param confForm
     *
     * @return
     */
    @NoAuth
    @Path("/item")
    public ActionResult getItem(ConfForm confForm) {
        PrintBeat.printBeat(beat);
        // 校验
        //
        ConfigFullModel configModel = null;
        try {
            configModel = configValidator4Fetch.verifyConfForm(confForm, false);
            return new JsonActionResult(configFetchMgr.getConfItemByParameter(configModel.getApp().getId(), configModel.getEnv().getId(), configModel.getVersion(), configModel.getKey()));

        } catch (Exception e) {
            LOG.warn(e.toString());
            return new JsonActionResult(ConfigUtils.getErrorVo(e.getMessage()));
        }

    }

    /**
     * 获取配置文件
     *
     * @return
     */
    @NoAuth
    @RequestMapping(value = "/file", method = RequestMethod.GET)
    @ResponseBody
    @Path("/file")
    public ActionResult getFile(ConfForm confForm) {
        PrintBeat.printBeat(beat);
        boolean hasError = false;

        //
        // 校验
        //
        ConfigFullModel configModel = null;
        try {
            configModel = configValidator4Fetch.verifyConfForm(confForm, false);

            if (hasError == false) {
                try {
                    //
                    Config config = configFetchMgr.getConfByParameter(configModel.getApp().getId(), configModel.getEnv().getId(), configModel.getVersion(), configModel.getKey(), DisConfigTypeEnum.FILE);
                    if (config == null) {
                        hasError = true;
                        throw new DocumentNotFoundException(configModel.getKey());
                    }
                    //API获取节点内容也需要同样做格式转换
                    return new JsonActionResult(downloadDspBill(configModel.getKey(), config.getValue()));

                } catch (Exception e) {
                    LOG.error(e.toString());
                }
            }

            if (confForm.getKey() != null) {
                throw new DocumentNotFoundException(confForm.getKey());
            } else {
                throw new DocumentNotFoundException("");
            }
        } catch (Exception e) {
            LOG.error(e.toString());
            hasError = true;
        }
        return null;
    }

    /**
     * 下载
     *
     * @param fileName
     *
     * @return
     */
    public ActionResult downloadDspBill(String fileName, String value) {

        try {
            PrintBeat.printBeat(beat);
            HttpHeaders header = new HttpHeaders();
            byte[] res = value.getBytes();

            String name = null;

            try {
                name = URLEncoder.encode(fileName, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            header.set("Content-Disposition", "attachment; filename=" + name);
            header.setContentLength(res.length);
            return new JsonActionResult(new HttpEntity<byte[]>(res, header));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private ActionResult getListImp(ConfForm confForm, boolean hasValue) {
        try {
            PrintBeat.printBeat(beat);
            //
            // 校验
            //
            ConfigFullModel configModel = configValidator4Fetch.verifyConfForm(confForm, true);

            List<Config> configs = configFetchMgr.getConfListByParameter(configModel.getApp().getId(), configModel.getEnv().getId(), configModel.getVersion(), hasValue);

            return new JsonActionResult(buildListSuccess(configs, configs.size()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
